package com.ibm.sova.abcd.cma.reqparser;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import products.hardware.configurator.cma.config.CFReportConverter;

import com.ibm.sova.abcd.cma.RequestParser;
import com.ibm.sova.abcd.cma.dto.*;

/**
 * This is an implementation of RequestParser interface, it is capable of parsing request data in CFR format. CFR2CSD converter utility is used to parse input CFR file data. Logging is performed using log4j.
 * 
 * Thread Safety: it immutable and thread safe
 */
public class CFRRequestParser implements RequestParser {
    /**
     * Represents the logger to perform logging.
     */
    private static Logger LOGGER = Logger.getLogger(CFRRequestParser.class);

    /**
     * Creates an instance of this class.
     * 
     * ###Params
     * None
     * 
     * ###Impl
     * None
     * 
     * ###Exceptions
     * None
     */
    public CFRRequestParser() {
    }

    /**
     * Parses request data and outputs an ABCDResponseData entity. 
     * 
     * It is possible that error might occur during parsing, all errors are stored in ABCDResponseData.overallMessages field, no exception is thrown.
     * 
     * ###Params
     * requestData - request data in byte array, cannot be null
     * 
     * ###Impl
     * 1. Create a string from input data: inputString=new String(requestData);
     * 2. Create a CSD converter: converter=new CFReportConverter();
     * 3. Convert request data to CSD XML string: csdXMLString=converter.convertCFRToCSDXML(inputString);
     * 4. Create SAX parser factory: SAXParserFactory factory = SAXParserFactory.newInstance();
     * 5. Create SAXParser: saxParser = factory.newSAXParser();
     * 6. Create handler: handler=new CSDXmlDataHandler();
     * 7. Parse xml document: saxParser.parse(new ByteArrayInputStream(csdXMLString.getBytes()), handler);
     * 8. Get response data: response=handler.getResponseData();
     * 9. return response;
     * 
     * Note, if any exception (not IAE) is thrown, catch it and run following logic:
     * ABCDResponseData response=new ABCDResponseData();
     * response.criticalErrors=true;
     * ErrorMessage errMsg=new ErrorMessage();
     * errMsg.severity="C";
     * errMsg.message="Request CFR data file is corrupted, cannot be parsed, inner error is [" + <exception stacktrace> + "]";
     * return response;
     * 
     * ###Exceptions
     * IllegalArgumentException - if any argument is invalid
     * CMARequestParsingException - if there is an error when parsing request data
     * @param requestData 
     * @return 
     */
    public ABCDResponseData parseRequestData(byte[] requestData) {
        String inputString = new String(requestData);
        CFReportConverter converter = new CFReportConverter();
        String csdXMLString = converter.convertCFRToCSDXML(inputString.getBytes());
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = null;
        try {
            saxParser = factory.newSAXParser();  
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        CSDXmlDataHandler handler = new CSDXmlDataHandler();
        try {
            saxParser.parse(new ByteArrayInputStream(csdXMLString.getBytes()), handler);
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        ABCDResponseData response = handler.getResponseData();
        return response;
    }
}

